import signal

import os

from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QThread, pyqtSignal
from SSHTunnelServer import SSHTunnel
import sys
import traceback
from SUi import *


class StartSSHTunnelThread(QThread):
    """导出视频子线程"""
    # 对外输出信号
    output_signal = pyqtSignal(str)
    tunnel_obj_signal = pyqtSignal(object)

    def __init__(self):
        super().__init__()

    def run(self):
        def print_to_signal(text):
            self.output_signal.emit(text)

        try:
            tunnel = SSHTunnel(callback=print_to_signal)
            self.tunnel_obj_signal.emit(tunnel)
            tunnel.start()
        except Exception as e:
            print(str(e))
            print_to_signal("Exception: " + str(e))


class StopSSHTunnelThread(QThread):
    """停止ssh隧道子线程"""

    def __init__(self, tunnel_obj):
        super().__init__()
        self.tunnel_obj = tunnel_obj

    def run(self):
        self.tunnel_obj.stop_all_threads()


class MyWindow(QMainWindow):
    """程序主线程"""

    def __init__(self):
        super().__init__()

        self.stop_ssh_thread = None
        self.tunnel_obj = None
        self.start_ssh_tunnel_thread = None

        # 标准实例化
        self.ui = Ui_SSHTunnelServer()
        self.ui.setupUi(self)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)  # 设置窗口背景透明
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)  # 隐藏边框

        # 启动阶段
        self.ui.stop_server_btn.setEnabled(False)  # 停止按钮置灰

        # 开始按钮点击事件到槽函数
        self.ui.start_server_btn.clicked.connect(self.start_processing)

        # 停止按钮点击事件
        self.ui.stop_server_btn.clicked.connect(self.stop_processing)

        # 关闭按钮事件
        self.ui.close_ui_btn.clicked.connect(self.close_processing)

        # 运行实例
        self.show()

    def start_processing(self):
        # 清除日志展示框中之前的输出
        self.ui.log_out.clear()

        try:
            # 创建并启动子线程
            self.start_ssh_tunnel_thread = StartSSHTunnelThread()
            self.start_ssh_tunnel_thread.output_signal.connect(self.update_output)
            self.start_ssh_tunnel_thread.tunnel_obj_signal.connect(self.set_tunnel_obj)
            self.start_ssh_tunnel_thread.start()
            self.ui.start_server_btn.setEnabled(False)  # 开始按钮置灰
            self.ui.stop_server_btn.setEnabled(True)  # 开始按钮置灰
        except Exception as e:
            # 获取详细的回溯信息
            tb_str = traceback.format_exception(type(e), e, e.__traceback__)
            error_msg = f"发生异常：{str(e)}\n回溯信息：\n{''.join(tb_str)}"
            self.ui.log_out.append(error_msg)

    def set_tunnel_obj(self, obj):
        self.tunnel_obj = obj

    def stop_processing(self):
        # 清除日志展示框中之前的输出
        self.ui.log_out.clear()
        if self.tunnel_obj:
            self.stop_ssh_thread = StopSSHTunnelThread(self.tunnel_obj)
            self.stop_ssh_thread.start()
        self.ui.stop_server_btn.setEnabled(False)  # 停止按钮置灰
        self.ui.start_server_btn.setEnabled(True)  # 停止按钮置灰

    def close_processing(self):
        self.stop_processing()
        os.kill(os.getpid(), signal.SIGTERM)

    def update_output(self, text):
        """日志输出框的日志输出函数, 该函数不会清空输出框"""
        if "Error" in text or "Exception" in text:
            self.ui.log_out.setStyleSheet("color: red;")
            if "Warning" in text:
                self.ui.log_out.setStyleSheet("color: blue;")
            self.ui.log_out.append(text)
        else:
            self.ui.log_out.setStyleSheet("color: blue;")
            self.ui.log_out.append(text)

    # 重构鼠标动作, 以下内容不需要任何改动, --------------------------------------------------------------
    def mousePressEvent(self, event):
        """重写鼠标点击事件"""
        if event.button() == QtCore.Qt.LeftButton:
            # 鼠标按下时设置为移动状态
            self.Move = True
            # 记录起始点坐标
            self.Point = event.globalPos() - self.pos()
            event.accept()

    def mouseMoveEvent(self, QMouseEvent):
        """移动时间"""
        # 切记这里的条件不能写死，只要判断move和鼠标执行即可！
        if QtCore.Qt.LeftButton and self.Move:
            # 移动到鼠标到达的坐标点！
            self.move(QMouseEvent.globalPos() - self.Point)
            QMouseEvent.accept()

    def mouseReleaseEvent(self, QMouseEvent):
        """结束事件"""
        self.Move = False
    # 重构鼠标动作, 以上内容不需要任何改动, --------------------------------------------------------------


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MyWindow()
    sys.exit(app.exec_())
